﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using _3DTicTacToe.Core;
using _3DTicTacToe.Net;


namespace _3DTicTacToe
{
    internal partial class GameWindow : Window
    {
        private Point _mLastPos;
        private bool _mDown;
        private TicTacToeGame _game;
        private bool _showStartWindow = true;

        private bool _turnWindowShown;
        private TurnListWindow _turnWindow;

        private bool _chatWindowShown;
        private NetChatWindow _chatWindow;

        public bool IsNetGame { get; private set; }

        void Init(TicTacToeGame game)
        {
            _game = game;

            // init 3d viewport
            model.Transform = new Transform3DGroup();

            // assign event handlers
            _game.OnTurn += DrawImageOnTurn;
            _game.OnTurn += GameOnTurn;
            _game.OnTurn += GameOnTurn1;
            _game.OnGameOver += GameOnGameOver;

            // prepare player panel
            GameOnTurn(null);
        }

        void GameOnGameOver(object sender, GameOverEventArgs e)
        {
            Action a = () =>
                {
                    if (e.IsDraw)
                    {
                        playerBorder.Background = Brushes.Black;
                        playerControl.Foreground = Brushes.White;
                        playerControl.Content = "Draw! You're all Losers!";
                    }
                    else
                    {
                        playerBorder.Background = new SolidColorBrush(e.WinningPlayer.Color);
                        playerControl.Foreground = new SolidColorBrush(InvertColor(e.WinningPlayer.Color));
                        playerControl.Content = e.WinningPlayer.Name + " wins!";
                    }

                    _showStartWindow = false;
                    menuBar.IsEnabled = false;

                    var gameOverWin = new GameOverWindow(e, _game, IsNetGame) { Owner = this, Topmost = true };
                    gameOverWin.Closing += GameOverWinClosing;
                    gameOverWin.Show();
                };
            Dispatcher.Invoke(a, null);
        }

        void GameOverWinClosing(object sender, CancelEventArgs e)
        {
            Close();
        }

        public GameWindow()
        {
            InitializeComponent();

#if DEBUG
            var debugMenuItem = new MenuItem { Header = "Debug" };

            var logMI = new MenuItem { Header = "Log Window" };
            logMI.Click += delegate { new LogViewWindow { Owner = this }.Show(); };

            debugMenuItem.Items.Add(logMI);
            menuBar.Items.Add(debugMenuItem);
#endif
        }

        public GameWindow(TicTacToeGame game)
            :this()
        {
            Init(game);
        }

        public GameWindow(NetGame game)
            :this()
        {
            Init(game);
            IsNetGame = true;

            gameMenuItem.IsEnabled = false;
            chatwindowMenuItem.IsEnabled = true;

            imgGrid.IsEnabled = game.NextPlayer == game.LocalPlayer;
            game.OnTurn += turn =>
                               {
                                   Action a = () => { imgGrid.IsEnabled = game.NextPlayer == game.LocalPlayer; };
                                   Dispatcher.Invoke(a, null);
                               };

            game.OnChatMessageReceived += message =>
                                              {
                                                  Action<string> a = msg =>
                                                                         {
                                                                             if (!_chatWindowShown)
                                                                                 chatwindowMenuItem_Click(null, null);
                                                                             _chatWindow.ChatMessageReceived(msg);
                                                                         };

                                                  Dispatcher.Invoke(a, message);
                                              };
            Closing += delegate { if (!game.IsOver) game.Shutdown(); };
        }

        private void Window_Closing(object sender, EventArgs e)
        {
            if (_turnWindowShown)
                _turnWindow.Close();

            if (_chatWindowShown)
                _chatWindow.Close();

            if (_showStartWindow)
                new StartWindow().Show();
        }

        // exit
        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            Application.Current.Shutdown();
        }

        // return to start: close
        private void MenuItem_Click_1(object sender, RoutedEventArgs e)
        {
            Close();
        }

        // new game
        private void MenuItem_Click_NewGame(object sender, RoutedEventArgs e)
        {
            _showStartWindow = false;
            new NewGameDialog().Show();
            Close();
        }

        // restart
        private void MenuItem_Click_Restart(object sender, RoutedEventArgs e)
        {
            var game = new TicTacToeGame(_game.PlayerOne, _game.PlayerTwo);
            _showStartWindow = false;
            
            new GameWindow(game).Show();
            Close();
        }

        void HandleTurnListWindowClosing(object sender, CancelEventArgs e)
        {
            _game.OnTurn -= _turnWindow.TurnHandler;
            turnListMenuItem.IsChecked = false;
            _turnWindowShown = false;
        }

        private void turnListMenuItem_Click(object sender, RoutedEventArgs e)
        {
            if  (_turnWindowShown)
            {
                _game.OnTurn -= _turnWindow.TurnHandler;
                _turnWindow.Close();
            }
            else
            {
                _turnWindow = new TurnListWindow(_game.Turns);
                _game.OnTurn += _turnWindow.TurnHandler;
                _turnWindow.Closing += HandleTurnListWindowClosing;
                _turnWindow.Show();
                Focus();

                _turnWindowShown = true;
            }
        }

        private void chatwindowMenuItem_Click(object sender, RoutedEventArgs e)
        {
            if (_chatWindowShown)
            {
                _chatWindow.Close();
            }
            else
            {
                _chatWindow = new NetChatWindow(_game as NetGame);
                _chatWindow.Closing += ChatWindowClosing;
                _chatWindowShown = true;
                _chatWindow.Show();
                Focus();
            }
        }

        void ChatWindowClosing(object sender, CancelEventArgs e)
        {
            _chatWindowShown = false;
            chatwindowMenuItem.IsChecked = false;
        }
    }
}
